/* ===================

AX2E (AXESCON XACML 2.0 Engine) is the Java authorization engine, which implements OASIS XACML 2.0 standard.
Copyright (C) 2007 AXESCON LLC

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA


Contact: AXESCON LLC - info{at}axescon.com

 =================== */
package axescon.xacml.xb.engine;

import axescon.xacml.api.AttributeSelectorEvaluator;
import axescon.xacml.api.ExpressionEvalIndeterminateException;
import axescon.xacml.api.XacmlException;
import axescon.xacml.model.ctx.XacmlCtx;
import axescon.xacml.model.ctx.StatusCode;
import axescon.xacml.model.ctx.impl.StatusImpl;
import axescon.xacml.model.policy.AttributeSelector;
import axescon.xacml.xb.ctx.XBAttrValueFactoryManager;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlRuntimeException;
import x0ContextSchemaOs.oasisNamesTcXacml2.RequestType;

/**
 * @author Date: Oct 11, 2005
 *         Responsibilities: evaluates AttributeSelector using XmlBeans API
 */
public class XBAttributeSelectorEvaluator implements AttributeSelectorEvaluator {
    /**
     * @param x
     * @param req, assumes having getLLObject() to return RequestType
     * @return
     * @throws ExpressionEvalIndeterminateException
     *
     */
    public axescon.xacml.model.policy.AttributeValue[] eval(AttributeSelector x, XacmlCtx req)
            throws ExpressionEvalIndeterminateException {

        assert x != null : "Null AttributeSelecetor passed to XB AttributeSelector Evaluator.";

        XmlCursor cur = ((RequestType) req.getLLObject()).newCursor();
        try {
            cur.selectPath(x.getRequestContextPath());
        } catch (XmlRuntimeException e) {

            throw new ExpressionEvalIndeterminateException(e);
        }
        axescon.xacml.model.policy.AttributeValue[] ret = getXbAttrValueFactoryManager().getAttributeValues(cur, x.getDataType());
        cur.dispose();

        if ((ret == null || ret.length == 0) && x.isMustBePresent()) {
            ExpressionEvalIndeterminateException missingAttrException =
                    new ExpressionEvalIndeterminateException("XBAttributeSelector can not evaluate AttributeSelector: " +
                            x + " to attribute.", XacmlException.ERR_CODE_PROCESSING_ATTRIBUTE_SELECTOR_EVAL_TO_NULL);
            missingAttrException.setStatus(new StatusImpl(StatusCode.INT_MISSING_ATTRIBUTE));
            throw missingAttrException;
        }
        return ret;

    }

    private XBAttrValueFactoryManager xbAttrValueFactoryManager;


    public XBAttrValueFactoryManager getXbAttrValueFactoryManager() {
        return xbAttrValueFactoryManager;
    }

    public void setXbAttrValueFactoryManager(XBAttrValueFactoryManager xbAttrValueFactoryManager) {
        this.xbAttrValueFactoryManager = xbAttrValueFactoryManager;
    }

    public void setDefaults() throws XacmlException {
        setXbAttrValueFactoryManager(new XBAttrValueFactoryManager(true));
    }

    public XBAttributeSelectorEvaluator() throws XacmlException {
        this(false);
    }

    public XBAttributeSelectorEvaluator(boolean setDefaults) throws XacmlException {
        if (setDefaults) setDefaults();
    }


}
